package com.sq.util.sql;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.RowMapper;

import com.sq.util.page.Dialect;
import com.sq.util.page.MysqlDialect;
import com.sq.util.page.Page;
import com.sq.util.page.PageQuery;

/**
 * Spring的JDBC实体基类
 * 
 */
public abstract class SpringJdbcEntity extends SpringJdbc {

    protected abstract Class<?> getEntityClass();

    private static Dialect dialect = new MysqlDialect();

    protected <T> Page<T> pageQuery(String sql, PageQuery pageQuery) {
        return pageQuery(sql, pageQuery, getEntityClass());
    }

    protected <T> Page<T> pageQuery(String sql, PageQuery pageQuery, Class<?> cls) {
        RowMapper<T> rowMapper = getRowMapper(cls);
        Map<String, Object> paramMap = pageQuery.getQueryParams();
        int allRecordNum = queryTotalItems(sql, paramMap);
        Page<T> page = new Page<T>(pageQuery.getPage(), allRecordNum, pageQuery.getSize());
        if (allRecordNum == 0) {
            page.setRecords(new LinkedList<T>());
            return page;
        } else if (allRecordNum <= pageQuery.getSize()) {
            List<T> list = namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);
            page.setRecords(list);
            return page;
        } else {
            sql = dialect.buildQueryPageSQL(sql, paramMap, page.getStartIndex(), page.getPageSize());
            List<T> list = namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);
            page.setRecords(list);
            return page;
        }
    }

    protected <T> T queryForObject(String sql, Object... args) {
        return queryForObject(getEntityClass(), sql, args);
    }

    protected <T> List<T> queryForList(String sql, Object... args) {
        return jdbcTemplate.query(sql, getRowMapper(getEntityClass()), args);
    }

    protected <T> List<T> queryForList(String sql, Map<String, ?> paramMap) {
        return queryForList(getEntityClass(), sql, paramMap);
    }

    private int queryTotalItems(String sql, Map<String, Object> paramMap) {
        sql = "select count(*)  from (" + sql + ")a ";
        return queryForInt(sql, paramMap);
    }

}